package com.bskj.kuaifu.service.impl;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bskj.common.bean.model.BoxRailInfo;
import com.bskj.common.bean.model.NoCarnoParkInfo;
import com.bskj.common.bean.model.NoCarnoParkRate;
import com.bskj.common.bean.model.ParkingLotBoxInfo;
import com.bskj.common.bean.model.ParkingLotCustomer;
import com.bskj.common.dao.BoxRailInfoDao;
import com.bskj.common.dao.NoCarnoParkInfoDao;
import com.bskj.common.dao.NoCarnoParkRateDao;
import com.bskj.common.dao.ParkingLotBoxInfoDao;
import com.bskj.common.dao.ParkingLotCustomerDao;
import com.bskj.common.dao.core.BaseDao;
import com.bskj.common.dao.core.FindRequestEntity;
import com.bskj.common.dao.core.OrderEnum;
import com.bskj.common.dao.core.WhereEnum;
import com.bskj.common.enums.ParkChargeTypeEnum;
import com.bskj.common.enums.RailTypeEnum;
import com.bskj.common.service.impl.BaseServiceImpl;
import com.bskj.common.utils.DateTimeUtil;
import com.bskj.kuaifu.bean.vo.UpRailMessage;
import com.bskj.kuaifu.bean.vo.req.NoCarnoReqVo;
import com.bskj.kuaifu.service.INoCarnoParkInfoService;

@Service
public class NoCarnoParkInfoServiceImpl extends BaseServiceImpl<NoCarnoParkInfo> implements INoCarnoParkInfoService {
	@Autowired
	private NoCarnoParkInfoDao noCarnoParkInfoDao;

	@Autowired
	private NoCarnoParkRateDao noCarnoParkRateDao;

	@Autowired
	private ParkingLotBoxInfoDao parkingLotBoxInfoDao;

	@Autowired
	private BoxRailInfoDao boxRailInfoDao;

	@Autowired
	private ParkingLotCustomerDao parkingLotCustomerDao;

	@Resource(name = "myAmqpTemplate")
	private AmqpTemplate amqpTemplate;

	public BaseDao<NoCarnoParkInfo> getBaseDao() {
		return noCarnoParkInfoDao;
	}

	public Map<String, Object> carIn(NoCarnoReqVo carInReq) throws Exception {
		// 校验参数合法性
		Map<String, Object> resultMap = new HashMap<>();
		Integer parkLotCustomerId = carInReq.getParkLotCustomerId();
		Integer boxId = carInReq.getBoxId();
		Integer railId = carInReq.getRailId();

		resultMap = validData(parkLotCustomerId, boxId, railId, RailTypeEnum.IN_RAIL);

		if (resultMap.get("result") != null && (boolean) resultMap.get("result")) {
			// 记录进场数据
			NoCarnoParkInfo noCarnoParkInfo = new NoCarnoParkInfo();
			noCarnoParkInfo.setAppid(carInReq.getAppId());
			noCarnoParkInfo.setOpenid(carInReq.getOpenId());
			noCarnoParkInfo.setParkingLotCustomerId(parkLotCustomerId);
			noCarnoParkInfo.setInRailId(railId);
			noCarnoParkInfo.setInTime(new Date());
			noCarnoParkInfo.setChargeType(0);

			noCarnoParkInfo.setCreateTime(new Date());
			noCarnoParkInfo.setUpdateTime(new Date());
			insert(noCarnoParkInfo);
			resultMap.put("result", true);
			resultMap.put("inTime", DateTimeUtil.date2String(noCarnoParkInfo.getInTime()));

			// MQ进场抬杆信息
			ParkingLotBoxInfo boxInfo = (ParkingLotBoxInfo) resultMap.get("boxInfo");
			BoxRailInfo railInfo = (BoxRailInfo) resultMap.get("railInfo");
			UpRailMessage upRailMsg = new UpRailMessage();
			upRailMsg.setParkLotId(parkLotCustomerId);
			upRailMsg.setBoxNo(boxInfo.getBoxNo());
			upRailMsg.setType(railInfo.getType());
			upRailMsg.setRailNo(railInfo.getRailNo());
			amqpTemplate.convertAndSend("upRailMsgKey", upRailMsg);
		}
		return resultMap;
	}

	public Map<String, Object> carOut(NoCarnoReqVo carInReq) throws Exception {
		// 校验参数合法性
		Map<String, Object> resultMap = new HashMap<>();
		Integer parkLotCustomerId = carInReq.getParkLotCustomerId();
		Integer boxId = carInReq.getBoxId();
		Integer railId = carInReq.getRailId();

		resultMap = validData(parkLotCustomerId, boxId, railId, RailTypeEnum.OUT_RAIL);

		if (resultMap.get("result") != null && (boolean) resultMap.get("result")) {
			// 查找出场数据，计算应收金额
			FindRequestEntity findReq = new FindRequestEntity();
			findReq.addWhere("appId", WhereEnum.EQ, carInReq.getAppId());
			findReq.addWhere("openId", WhereEnum.EQ, carInReq.getOpenId());
			findReq.addWhere("charge_type", WhereEnum.EQ, 0);
			findReq.addWhere("parking_lot_customer_id", WhereEnum.EQ, parkLotCustomerId);
			findReq.addOrder("in_time", OrderEnum.DESC);
			findReq.setPage(1, 1);

			List<NoCarnoParkInfo> noCarnoParkInfoList = find(findReq);
			if (noCarnoParkInfoList != null && noCarnoParkInfoList.size() > 0) {
				NoCarnoParkInfo noCarnoParkInfo = noCarnoParkInfoList.get(0);
				if(noCarMoney(noCarnoParkInfo)>=0){
					noCarnoParkInfo.setCharge(noCarMoney(noCarnoParkInfo));
				}else {
					resultMap.put("result", false);
					resultMap.put("msg", "参数有问题");
				}
				
				if(noCarnoParkInfo.getCharge() == 0) {
					noCarnoParkInfo.setChargeType(ParkChargeTypeEnum.PLATFROM_PAY.getKey());
				}
				
				noCarnoParkInfo.setOutRailId(railId);
				noCarnoParkInfo.setOutTime(new Date());
				noCarnoParkInfo.setUpdateTime(new Date());

				update(noCarnoParkInfo);

				resultMap.put("result", true);
				resultMap.put("inTime", DateTimeUtil.date2String(noCarnoParkInfo.getInTime()));
				resultMap.put("outTime", DateTimeUtil.date2String(noCarnoParkInfo.getOutTime()));
				resultMap.put("charge", noCarnoParkInfo.getCharge());
				resultMap.put("parkId", noCarnoParkInfo.getId());
			} else {
				// TODO 找不到入场数据
				resultMap.put("result", false);
				resultMap.put("msg", "找不到入场记录");
			}
		}
		return resultMap;
	}

	private Integer noCarMoney(NoCarnoParkInfo noCarnoParkInfo) throws Exception {
		long time = System.currentTimeMillis() - noCarnoParkInfo.getInTime().getTime();
		DecimalFormat df = new DecimalFormat("#.#");
		double hour = Double.parseDouble(df.format(time / 1000 / 60 / 60));
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("parking_lot_cust_id", WhereEnum.EQ, noCarnoParkInfo.getParkingLotCustomerId());
		List<NoCarnoParkRate> noCarnoParkRates = noCarnoParkRateDao.find(findReq);
		if (noCarnoParkRates != null && noCarnoParkRates.size() > 0) {
			NoCarnoParkRate noCarnoParkRate = noCarnoParkRates.get(0);
			if (hour < noCarnoParkRate.getStegeOneTime()) {// 停车时间小于免费时间
				BoxRailInfo railInfo = boxRailInfoDao.get(noCarnoParkInfo.getOutRailId());
				if (railInfo != null) {
					ParkingLotBoxInfo boxInfo = parkingLotBoxInfoDao.get(railInfo.getBoxId());
					if (boxInfo != null) {
						UpRailMessage upRailMsg = new UpRailMessage();
						upRailMsg.setBoxNo(boxInfo.getBoxNo());
						upRailMsg.setParkLotId(boxInfo.getParkLotCustomerId());
						upRailMsg.setType(RailTypeEnum.OUT_RAIL.getKey());
						upRailMsg.setRailNo(railInfo.getRailNo());
						amqpTemplate.convertAndSend("upRailMsgKey", upRailMsg);
					}
				}
				return 0;
			} else if (hour < (noCarnoParkRate.getStegeTwoTime() + noCarnoParkRate.getStegeOneTime())) {// 停车时间小于第一收费时间的最大时间
				return noCarnoParkRate.getStegeTwoRate() * 10;
			} else {
				int times = (int) (hour - (noCarnoParkRate.getStegeTwoTime() + noCarnoParkRate.getStegeOneTime()));
				Integer money = ((int) ((times) / noCarnoParkRate.getStegeThreePerTime()) + 1)
						* noCarnoParkRate.getStegeThreePerRate() * 10+noCarnoParkRate.getStegeTwoRate() * 10;
				return money;
			}
		}
		return -1;
	}

	public Map<String, Object> registerBox(String boxNo, String boxName, Integer parkLotId, String parkLotUuid,
			String rails) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		ParkingLotCustomer lotCustomer = parkingLotCustomerDao.get(parkLotId);
		if (lotCustomer == null || !lotCustomer.getUuid().equals(parkLotUuid)) {
			resultMap.put("result", false);
			resultMap.put("msg", "停车场数据不合法");
			return resultMap;
		}

		// 注册岗亭信息
		ParkingLotBoxInfo boxInfo = new ParkingLotBoxInfo();
		boxInfo.setBoxName(boxName);
		boxInfo.setBoxNo(boxNo);
		boxInfo.setParkLotCustomerId(parkLotId);
		boxInfo.setParkLotCustomerUuid(parkLotUuid);
		boxInfo.setCreateTime(new Date());
		boxInfo.setUpdateTime(new Date());
		parkingLotBoxInfoDao.insert(boxInfo);

		// 注册栏杆信息
		String[] railsArry = rails.split(",");
		for (String rail : railsArry) {
			String[] details = rail.split("_");
			if (details.length != 2) {
				throw new Exception("栏杆数据不合法");
			}
			int railType = Integer.valueOf(details[0]);
			String railNo = details[1];
			BoxRailInfo boxRail = new BoxRailInfo();
			boxRail.setBoxId(boxInfo.getId());
			boxRail.setRailNo(railNo);
			boxRail.setType(railType);
			boxRail.setCreateTime(new Date());
			boxRail.setUpdateTime(new Date());
			boxRailInfoDao.insert(boxRail);
		}
		resultMap.put("result", true);
		resultMap.put("msg", "注册成功");
		return resultMap;
	}

	private Map<String, Object> validData(Integer parkLotCustomerId, Integer boxId, Integer railId, RailTypeEnum type) {
		Map<String, Object> resultMap = new HashMap<>();
		ParkingLotCustomer lotCustomer = parkingLotCustomerDao.get(parkLotCustomerId);
		if (lotCustomer == null) {
			resultMap.put("result", false);
			resultMap.put("msg", "停车场不存在");
			return resultMap;
		}

		ParkingLotBoxInfo boxInfo = parkingLotBoxInfoDao.get(boxId);
		if (boxInfo == null || !parkLotCustomerId.equals(boxInfo.getParkLotCustomerId())) {
			resultMap.put("result", false);
			resultMap.put("msg", "岗亭数据不合法");
			return resultMap;
		}

		BoxRailInfo boxRail = boxRailInfoDao.get(railId);
		if (boxRail == null || !boxId.equals(boxRail.getBoxId()) || boxRail.getType() != type.getKey()) {
			resultMap.put("result", false);
			resultMap.put("msg", "抬杆数据不合法");
			return resultMap;
		}
		resultMap.put("result", true);
		resultMap.put("parkLotName", lotCustomer.getName());
		resultMap.put("boxInfo", boxInfo);
		resultMap.put("railInfo", boxRail);
		return resultMap;
	}
}
